package com.gym.core.hash.my;

import java.util.TreeSet;


/**
 * 模拟一致性hash的扩容
 * @author xinchun.wang
 */
public class Test {
	private static TreeSet<Point> virualNodes = new TreeSet<Point>();

	public static void main(String[] args) {
		final long maxValue = 100000;
		final long minValue = 0;
		
		//每次增加的步长
		final long width = maxValue/100;
		
		//缓存的数量
		int cacheCount = 10;
		long begin = minValue;
		
		//初始化通过取模分配到 0->cacheCount 之间的缓存
		int i= 0;
		while (begin < (maxValue - width)) {
			virualNodes.add(new Point(begin,begin + width,String.valueOf("Cache"+(i++%cacheCount))));
			
			begin = begin + width +1;
		}
		virualNodes.add(new Point(begin,maxValue,String.valueOf("Cache"+(i++%cacheCount))));

		System.out.println(virualNodes);

		
		//扩容1台机器
		TreeSet<Point> virualNodes2 = new TreeSet<Point>();
		cacheCount = cacheCount +1;
		for(Point item : virualNodes){
			long newEnd = item.begin+(item.end-item.begin)/(cacheCount);
			long end = item.end;
			virualNodes2.add(new Point(item.begin,newEnd,"Cache10"));
			virualNodes2.add(new Point(newEnd+1,end,item.getDesc()));
		}
		System.out.println(virualNodes2);
		
		
		//再扩容1台机器
		cacheCount = cacheCount +1;
		TreeSet<Point> virualNodes3 = new TreeSet<Point>();
		for(Point item : virualNodes2){
			long newEnd = item.begin+(item.end-item.begin)/(cacheCount);
			long end = item.end;
			virualNodes3.add(new Point(item.begin,newEnd,"Cache11"));
			virualNodes3.add(new Point(newEnd+1,end,item.getDesc()));
		}
		
		System.out.println(virualNodes3);
		System.out.println(virualNodes.higher(new Point(6)).getDesc());
		System.out.println(virualNodes2.higher(new Point(6)).getDesc());
		System.out.println(virualNodes3.higher(new Point(6)).getDesc());
	}
	
	
	 public  static class Point implements Comparable<Point> {
	        private long point;
	        private long begin;
	        private long end;

	        private String desc;

	        public Point(long point) {
	            this.point = point;
	        }

	        public Point(long begin,long end, String desc) {
	            this.point = end;
	            this.desc = desc;
	            this.begin = begin;
	            this.end = end;
	        }

	        public long getPoint() {
	            return point;
	        }

	        public String getDesc() {
	            return desc;
	        }

	        public String toString() {
	            StringBuffer sb = new StringBuffer();
	            sb.append("{").append(begin).append("<->"+end+":").append(desc).append("}");
	            return sb.toString();
	        }

	        @Override
	        public int compareTo(Point o) {
	            if (point == o.getPoint()) {
	                return 0;
	            }
	            if (point < o.getPoint()) {
	                return -1;
	            }
	            return 1;
	        }
	    }
}
